package cn.redsoft.tools.util;

import static java.util.Objects.requireNonNull;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;

public abstract class StreamUtils {

	public static final int buffer_size = 4096;
	public static final String default_encoding = "UTF-8";

	/**
	 * <font color="red">传入的 {@code in} 和 {@code out} 都没有在代码内部关闭</font>
	 * 
	 * @param in
	 * @param out
	 * @return 复制的字节数
	 * @throws IOException
	 */
	public static int copy(InputStream in, OutputStream out) throws IOException {
		requireNonNull(in, "输入流为空");
		requireNonNull(out, "输出流为空");
		int count = 0;
		byte[] bs = new byte[buffer_size];
		int len = -1;
		while ((len = in.read(bs)) != -1) {
			out.write(bs, 0, len);
			count += len;
		}
		out.flush();
		return count;
	}

	/**
	 * 
	 * @param in
	 * @param out
	 * @return 复制的字符数
	 * @throws IOException
	 */
	public static int copy(Reader in, Writer out) throws IOException {
		requireNonNull(in);
		requireNonNull(out);
		int count = 0;
		int len = -1;
		char[] buffer = new char[buffer_size];
		while ((len = in.read(buffer)) != -1) {
			out.write(buffer, 0, len);
			count += len;
		}
		out.flush();
		return count;
	}

	/**
	 * 将给定字符串 {@code str} 中的内容复制到指定的输出流 {@code out}
	 * 
	 * @param str
	 * @param out
	 * @param encoding
	 * @throws IOException
	 */
	public static void copy(String str, OutputStream out, String encoding)
			throws IOException {
		requireNonNull(str, "输入字符串为空.");
		requireNonNull(out, "输出流为空.");
		requireNonNull(encoding, "编码方式为空.");
		Writer writer = new OutputStreamWriter(out, encoding);
		writer.write(str);
		writer.flush();
	}

	public static void copy(byte[] bytes, OutputStream out) throws IOException {
		requireNonNull(out, "输出流为空.");
		requireNonNull(bytes, "指定的字节数组为空.");
		out.write(bytes);
	}

	/**
	 * 将给定的输入流中的内容复制到字符串
	 * 
	 * @param in
	 * @param encoding
	 * @return
	 * @throws IOException
	 */
	public static String copy2String(InputStream in, String encoding)
			throws IOException {
		requireNonNull(in, "输入流为空.");
		if (encoding == null)
			encoding = default_encoding;
		StringBuilder sb = new StringBuilder();
		int len = -1;
		char[] cbuf = new char[buffer_size];
		InputStreamReader reader = new InputStreamReader(in, encoding);
		while ((len = reader.read(cbuf)) != -1) {
			sb.append(cbuf, 0, len);
		}
		return sb.toString();
	}

	/**
	 * 将给定的输入流的内容复制到字节数组
	 * 
	 * @param in
	 * @return
	 * @throws IOException
	 */
	public static byte[] copyToByteArray(InputStream in) throws IOException {
		ByteArrayOutputStream out = new ByteArrayOutputStream(buffer_size);
		copy(in, out);
		return out.toByteArray();
	}
}
